import tkinter as tk
from tkinter import scrolledtext,messagebox
import hashlib
import base64
from itertools import cycle
import string
import random

message=['我国已是网络大国','我们要立足自主创新','互相连接的计算机网络形成互联网','我国网民规模世界第一']
class CryptoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("加密和解密")
        self.root.resizable(False, False)

        self.init_gui()
        self.center_window()

    def init_gui(self):
        [self.root.grid_rowconfigure(i, weight=1) for i in range(5)]
        [self.root.grid_columnconfigure(j, weight=1) for j in range(7)]
        
        self.key_label = tk.Button(self.root, text="密码", command=self.gen_key)
        self.key_label.grid(row=0, column=0, sticky="ew", padx=5)
        self.key_entry = tk.Entry(self.root)
        self.key_entry.grid(row=0, column=1, columnspan=6,sticky="ew", padx=10)

        self.plaintext_label = tk.Button(self.root, text="明文",command=self.gen_txt)
        self.plaintext_label.grid(row=1, column=0, sticky="ew", padx=5)

        self.ciphertext_label = tk.Button(self.root, text="密文",command=self.gen_encry_txt)
        self.ciphertext_label.grid(row=1, column=4, sticky="ew", padx=5)

        self.plaintext_area = scrolledtext.ScrolledText(self.root, height=5, width=10)
        self.plaintext_area.grid(row=2, column=0, rowspan=3, columnspan=3, sticky="nsew", padx=5, pady=5)

        self.ciphertext_area = scrolledtext.ScrolledText(self.root, height=5, width=10)
        self.ciphertext_area.grid(row=2, column=4, rowspan=3, columnspan=3, sticky="nsew", padx=5, pady=5)

        self.encrypt_button = tk.Button(self.root, text="加密", command=self.encrypt)
        self.encrypt_button.grid(row=2,column=3, sticky="ew", padx=5, pady=5)
        self.decrypt_button = tk.Button(self.root, text="解密", command=self.decrypt)
        self.decrypt_button.grid(row=3, column=3, sticky="ew", padx=5, pady=5)

    def gen_key(self):
        characters = string.ascii_letters + string.digits + string.punctuation
        password = ''.join(random.choice(characters) for _ in range(8))
        self.key_entry.delete(0, tk.END)
        self.key_entry.insert(0, password)

    def gen_encry_txt(self):
        key = self.key_entry.get().encode()
        key_hash = hashlib.md5(key).digest()
        plaintext = random.choice(message).encode()
        plaintext = base64.b64encode(plaintext)
        xor_key = cycle(key_hash)
        result = bytes([a ^ next(xor_key) for a in plaintext])
        result_str = base64.b64encode(result).decode()
        self.ciphertext_area.delete('1.0', tk.END)
        self.ciphertext_area.insert('1.0', result_str)

    def gen_txt(self):
        self.plaintext_area.delete('1.0', tk.END)
        self.plaintext_area.insert('1.0', random.choice(message))

    def insert_text_after_delay(self, text_area, text, delay=200):
        text_area.delete("1.0", tk.END)
        text_area.after(delay, text_area.insert, tk.END, text)

    def encrypt(self):
        try:
            key = self.key_entry.get().encode()
            key_hash = hashlib.md5(key).digest()
            plaintext = self.plaintext_area.get("1.0", tk.END).strip().encode()
            plaintext = base64.b64encode(plaintext)
            xor_key = cycle(key_hash)
            result = bytes([a ^ next(xor_key) for a in plaintext])
            result_str = base64.b64encode(result).decode()
            self.insert_text_after_delay(self.ciphertext_area,result_str)
        except Exception as e:
            messagebox.showerror('错误','加密过程出现错误！请重新操作！')

    def decrypt(self):
        try:
            key = self.key_entry.get().encode()
            key_hash = hashlib.md5(key).digest()
            ciphertext = self.ciphertext_area.get("1.0", tk.END).strip().encode()
            ciphertext = base64.b64decode(ciphertext)
            xor_key = cycle(key_hash)
            result = bytes([a ^ next(xor_key) for a in ciphertext])
            result_str = base64.b64decode(result).decode()
            self.insert_text_after_delay(self.plaintext_area,result_str)
        except Exception as e:
            messagebox.showerror('错误', '解密过程出现错误！请重新操作！')

    def center_window(self):
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        window_width = 460
        window_height = 220
        x_cordinate = int((screen_width/2) - (window_width/2))
        y_cordinate = int((screen_height/2) - (window_height/2))
        self.root.geometry(f"{window_width}x{window_height}+{x_cordinate}+{y_cordinate}")


if __name__ == "__main__":
    root = tk.Tk()
    app = CryptoApp(root)
    root.mainloop()